<template>
  <u-popup v-model="show" @close="close" @open="open" :mode="mode" length="60%" :mask="mask" :closeable="closeable"
    :close-icon-pos="closeIconPos">
    <view class="popup">
      <view class="popup-hd">
        <view class="popup-title">
          请选择用户
          <view class="right-buttons">
            <view class="btn" @click="submit">确认</view>
            <view class="btn" @click="clearAll">清空</view>
          </view>
        </view>
        <view class="checkbox-list">
          <u-checkbox @change="checkboxChange" v-model="resultData.byCheck1" name="by1">备用1</u-checkbox>
          <u-checkbox @change="checkboxChange" v-model="resultData.byCheck2" name="by2">备用2</u-checkbox>
          <u-checkbox @change="checkboxChange" v-model="resultData.byCheck3" name="by3">备用3</u-checkbox>
          <u-checkbox @change="checkboxChange" v-model="resultData.byCheck4" name="by4">备用4</u-checkbox>
        </view>
      </view>
      <view class="popup-bd">
        <scroll-view class="tab-list menu-scroll-view" :scroll-top="scrollTop" :scroll-into-view="itemId"
          scroll-with-animation scroll-y>
          <view v-for="(item, index) in data" :key="index" class="tab-item" :class="[current == index ? 'active' : '']"
            @tap.stop="swichMenu(index)">
            {{item.groupName}}
          </view>
        </scroll-view>
        <scroll-view class="right-box" :scroll-top="scrollRightTop" @scroll="rightScroll" scroll-with-animation
          scroll-y>
          <view class="user-group-list">
            <view v-for="(item , index) in data" :key="index" :id="'item' + index" class="user-group-item">
              <view class="user-group-title">
                <u-checkbox v-model="item.checked" :name="item.id" @change="groupChange">{{item.groupName}}</u-checkbox>
              </view>
              <view class="user-list">
                <view v-for="(item1, index1) in item.userList" :key="index1" class="user-item"
                  :class="item1.checked ? 'checked' : ''" @click="item1.checked = !item1.checked">{{item1.userName}}
                </view>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>
    </view>
  </u-popup>
</template>
<script>
  export default {
    name: "JsChooseGroup",
    props: {
      // 模式
      mode: {
        type: String,
        default: 'bottom'
      },
      // 是否显示遮罩
      mask: {
        type: Boolean,
        default: true
      },
      // 是否可以关闭
      closeable: {
        type: Boolean,
        default: false
      },
      closeIconPos: {
        type: String,
        default: 'top-right'
      },
      value: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        scrollTop: 0, //tab标题的滚动条位置
        oldScrollTop: 0,
        current: 0, // 预设当前项的值
        menuHeight: 0, // 左边菜单的高度
        menuItemHeight: 0, // 左边菜单item的高度
        itemId: '', // 栏目右边scroll-view用于滚动的id
        data: null,
        menuItemPos: [],
        arr: [],
        scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
        timer: null, // 定时器
        tagShow: false,
        show: false,
        resultData: {
          byCheck1: false,
          byCheck2: false,
          byCheck3: false,
          byCheck4: false,
          selectedData: [],
        }
      }
    },
    onLoad() {

    },
    created() {
      this.$u.api.message.msgGroupUser.ownerList().then(res => {
        if (!res.data || res.data.length == 0) {
          return;
        }
        res.data.forEach((item) => {
          item.checked = false;
          item.userList.forEach((userItem) => {
            userItem.checked = false;
          })
        })
        this.data = res.data;
        this.getMenuItemTop()
      });
    },
    onReady() {

    },
    methods: {
      // 点击左边的栏目切换
      async swichMenu(index) {
        if (this.arr.length == 0) {
          await this.getMenuItemTop();
        }
        if (index == this.current) return;
        this.scrollRightTop = this.oldScrollTop;
        this.$nextTick(function() {
          this.scrollRightTop = this.arr[index];
          this.current = index;
          this.leftMenuStatus(index);
        })
      },
      // 获取一个目标元素的高度
      getElRect(elClass, dataVal) {
        new Promise((resolve, reject) => {
          const query = uni.createSelectorQuery().in(this);
          query.select('.' + elClass).fields({
            size: true
          }, res => {
            // 如果节点尚未生成，res值为null，循环调用执行
            if (!res) {
              setTimeout(() => {
                this.getElRect(elClass);
              }, 10);
              return;
            }
            this[dataVal] = res.height;
            resolve();
          }).exec();
        })
      },
      // 观测元素相交状态
      async observer() {
        this.data.map((val, index) => {
          let observer = uni.createIntersectionObserver(this);
          // 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
          // 如果跟.right-box底部相交，就动态设置左边栏目的活动状态
          observer.relativeTo('.right-box', {
            top: 0
          }).observe('#item' + index, res => {
            if (res.intersectionRatio > 0) {
              let id = res.id.substring(4);
              this.leftMenuStatus(id);
            }
          })
        })
      },
      // 设置左边菜单的滚动状态
      async leftMenuStatus(index) {
        this.current = index;
        // 如果为0，意味着尚未初始化
        if (this.menuHeight == 0 || this.menuItemHeight == 0) {
          await this.getElRect('menu-scroll-view', 'menuHeight');
          await this.getElRect('tab-item', 'menuItemHeight');
        }
        // 将菜单活动item垂直居中
        this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
      },
      // 获取右边菜单每个item到顶部的距离
      getMenuItemTop() {
        new Promise(resolve => {
          let selectorQuery = uni.createSelectorQuery();
          selectorQuery.selectAll('.user-group-item').boundingClientRect((rects) => {
            // 如果节点尚未生成，rects值为[](因为用selectAll，所以返回的是数组)，循环调用执行
            if (!rects.length) {
              setTimeout(() => {
                this.getMenuItemTop();
              }, 10);
              return;
            }
            rects.forEach((rect) => {
              // 这里减去rects[0].top，是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
              this.arr.push(rect.top - rects[0].top);
              resolve();
            })
          }).exec()
        })
      },
      // 右边菜单滚动
      async rightScroll(e) {
        this.oldScrollTop = e.detail.scrollTop;
        if (this.arr.length == 0) {
          await this.getMenuItemTop();
        }
        if (this.timer) return;
        if (!this.menuHeight) {
          await this.getElRect('menu-scroll-view', 'menuHeight');
        }
        setTimeout(() => { // 节流
          this.timer = null;
          // scrollHeight为右边菜单垂直中点位置
          let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
          for (let i = 0; i < this.arr.length; i++) {
            let height1 = this.arr[i];
            let height2 = this.arr[i + 1];
            // 如果不存在height2，意味着数据循环已经到了最后一个，设置左边菜单为最后一项即可
            if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
              this.leftMenuStatus(i);
              return;
            }
          }
        }, 10)
      },
      close() {
        this.show = false;
      },
      open() {
        this.show = true;
      },
      getSelectedData() {
        let selectData = [];
        this.data.forEach((item) => {
          item.userList.forEach((userItem) => {
            if (userItem.checked) {
              selectData.push(userItem);
            }
          })
        })
        return selectData;
      },
      groupChange(e) {
        this.data.forEach((item) => {
          if (e.name == item.id) {
            item.userList.forEach((userItem) => {
              userItem.checked = e.value;
            })
            return;
          }
        })
        this.resultData.selectedData = this.getSelectedData();
      },
      groupUserChange(e) {
        this.data.forEach((item) => {
          item.userList.forEach((userItem) => {
            if (userItem.id == e.name) {
              userItem.checked = e.value;
            }
          })
        })
        this.resultData.selectedData = this.getSelectedData();
      },
      tagClick(row) {
        this.data.forEach((item) => {
          item.userList.forEach((userItem) => {
            if (row.id == userItem.id) {
              userItem.checked = false;
            }
          })
        })
        this.resultData.selectedData = this.getSelectedData();
      },
      clearAll() {
        this.data.forEach((item) => {
          item.checked = false;
          item.userList.forEach((userItem) => {
            userItem.checked = false;
          })
        })
        this.resultData.selectedData = [];
      },
      checkboxChange(e) {
        if (e.name == 'by1') {
          this.resultData.byCheck1 = true;
        } else if (e.name == 'by2') {
          this.resultData.byCheck2 = true;
        } else if (e.name == 'by3') {
          this.resultData.byCheck3 = true;
        } else if (e.name == 'by4') {
          this.resultData.byCheck4 = true;
        }
      },
      submit() {
        this.$emit('submit');
      },
      getData() {
        return this.resultData;
      },
    }
  }
</script>

<style lang="scss" scoped>
  .u-drawer {
    /deep/ .u-drawer-content {
      border-radius: 40rpx 40rpx 0 0;
      padding-top: 40rpx;
      background: #fff;
    }
  }

  .popup {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: #f7f7f7;

    /deep/ .u-checkbox__icon-wrap {
      border-radius: 50%;

      &.u-checkbox__icon-wrap--checked {
        background: #1676FE;
      }
    }

    /deep/ .u-checkbox__label {
      margin: 0 32rpx 0 16rpx;
      font-size: 28rpx;
      font-weight: 500;
      color: #333;
    }
  }

  .popup-hd {
    padding: 0 32rpx 32rpx;
    margin-bottom: 16rpx;
    background: #fff;
  }

  .popup-bd {
    display: flex;
    flex: 1;
    overflow: hidden;
  }

  .popup-title {
    display: flex;
    align-items: center;
    font-size: 28rpx;
    font-weight: 700;
    color: #333;
  }

  .right-buttons {
    margin-left: auto;

    .btn {
      display: inline-block;
      height: 56rpx;
      border-radius: 56rpx;
      padding: 0 24rpx;
      line-height: 56rpx;
      font-size: 28rpx;
      font-weight: 500;
      color: #fff;
      background: #1676FE;

      &+.btn {
        margin-left: 16rpx;
        background: #D43030;
      }
    }
  }

  .checkbox-list {
    margin-top: 24rpx;
  }

  .tab-list {
    flex-shrink: 0;
    width: 176rpx;
    height: 100%;
  }

  .tab-item {
    position: relative;
    padding: 32rpx 24rpx;
    font-size: 24rpx;
    font-weight: 500;
    color: #666;

    &.active {
      font-weight: 700;
      color: #005EFF;
      background: #fff;

      &::before {
        content: '';
        position: absolute;
        top: 50%;
        left: -4rpx;
        display: inline-block;
        width: 8rpx;
        height: 32rpx;
        border-radius: 8rpx;
        background: #005EFF;
        transform: translateY(-50%);
      }
    }
  }

  .user-group-list {
    padding: 0 24rpx;
    background: #fff;
  }

  .user-group-item {
    border-bottom: 1px solid #eee;
    padding-bottom: 24rpx;
  }

  .user-group-title {
    padding: 24rpx 0;
    font-size: 28rpx;
    font-weight: 700;
    color: #333;
  }

  .user-item {
    display: inline-block;
    border: 1px solid transparent;
    border-radius: 8rpx;
    padding: 0 24rpx;
    margin-right: 16rpx;
    margin-bottom: 16rpx;
    line-height: 56rpx;
    font-size: 28rpx;
    font-weight: 500;
    color: #333;
    background: #f7f7f7;

    &.checked {
      border-color: #3989FC;
      color: #3989FC;
      background: #E1EDFF;
    }
  }
</style>